/** 初始化 cesium 地图信息 */
import * as Cesium from 'cesium';

/** 初始化创建viewer */
export const initMapViewer = (id: string, options?: Cesium.Viewer.ConstructorOptions) => {
  const viewer = new Cesium.Viewer(id, {
    // contextOptions: {
    //   requestWebgl1: true,
    // },
    /** UI控制选项 */
    animation: false, // 是否显示动画控件，左下角播放/暂停按钮
    baseLayerPicker: false, // 是否显示底层选择器
    fullscreenButton: false, // 是否显示全屏按钮
    vrButton: false, // 是否显示VR模组按钮，默认false,
    geocoder: false, // 是否显示地理编码搜索框，或自定义搜索服务
    homeButton: false, //是否显示返回初始视角按钮
    infoBox: false, //是否显示点击实体时的信息框
    sceneModePicker: false, //是否显示2D/3D模式切换按钮
    selectionIndicator: false, // 是否显示选中实体的高亮指示器
    timeline: false, // 是否显示时间轴
    navigationHelpButton: false, // 是否显示导航帮助按钮
    navigationInstructionsInitiallyVisible: false, // 导航帮助是否默认展开
    projectionPicker: false, // 是否显示投影方式选择器
    /** 场景渲染选项 */
    scene3DOnly: false, //是否强制只使用3D模式（禁用2D和哥伦布视图）
    shouldAnimate: false, // 是否自动开始动画
    terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY, // 地形阴影模式：DISABLED、ENABLED、RECEIVE_ONLY
    orderIndependentTranslucency: false, // 是否使用顺序无关的半透明渲染
    requestRenderMode: true, // 是否启用按需渲染模式（节省资源）
    maximumRenderTimeChange: 0, // 在按需渲染模式下，最大允许的渲染时间变化（秒）
    useDefaultRenderLoop: true, // 是否使用默认的渲染循环
    targetFrameRate: 60, // 目标帧率，当useDefaultRenderLoop为true时有效
    /** 数据提供选项 */
    // skyBox: false, // 禁用天空盒
    // skyAtmosphere: false, // 禁用大气效果.
    // shadows: false, // 禁用阴影
    /** 地图与地球选项 */
    baseLayer: false, // 基础影像图层，设为false则不创建
    sceneMode: Cesium.SceneMode.COLUMBUS_VIEW, // 初始场景模式
    // sceneMode: Cesium.SceneMode.SCENE2D, // 初始场景模式
    // mapMode2D: Cesium.MapMode2D.ROTATE, // 2D地图下的默认行为
    // globe: false,
    /**  性能与高级选项 */
    /** 其他选项 */
    creditContainer: document.createElement('div'), // 版权信息，左下角logo,创建一个空的div
    // mapProjection: new ZeroTo360Projection(),
    ...options,
  });
  viewer.resolutionScale = window.devicePixelRatio;
  viewer.trackedEntityChanged.addEventListener(function () {
    viewer.trackedEntity = undefined;
  });
  const gl = viewer.scene.canvas.getContext('webgl2');
  console.log(gl ? 'WebGL 2.0' : 'WebGL 1.0');

  // viewer.scene.setTerrain(new Cesium.Terrain(Cesium.createWorldTerrainAsync()));
  // viewer.scene.setTerrain(new Cesium.Terrain(Cesium.CesiumTerrainProvider.fromUrl(import.meta.env.VITE_TERRAIN_URL)));

  // 全局禁用双击事件
  viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
  initImageLayer(viewer);
  initScene(viewer);
  initCamera(viewer);
  return viewer;
};

// const requestTile = Cesium.CesiumTerrainProvider.prototype.requestTileGeometry;
// Cesium.CesiumTerrainProvider.prototype.requestTileGeometry = function (x, y, level, request) {
//   const totalTiles = this.tilingScheme.getNumberOfXTilesAtLevel(level);
//   const tileX = x < (totalTiles - 1) / 2 ? x + totalTiles / 2 : x - totalTiles / 2;
//   return requestTile.call(this, tileX, y, level, request);
// };
/** 使用自定义图层 */
const initImageLayer = (viewer: Cesium.Viewer) => {
  viewer.imageryLayers.addImageryProvider(
    new Cesium.UrlTemplateImageryProvider({
      url: import.meta.env.VITE_CESIUM_MAP,
      minimumLevel: import.meta.env.VITE_MIN_MAP,
      maximumLevel: import.meta.env.VITE_MAX_MAP,
    })
  );
};
// class CustomImageryProvider extends Cesium.UrlTemplateImageryProvider {
//   _url = '';
//   constructor(options: any) {
//     super({
//       ...options,
//     });
//     this._url = options.url;
//   }
//   requestImage(x: any, y: any, level: any, request: any) {
//     // 将0-360经度转换为-180到180
//     const minLon = (x / Math.pow(2, level)) * 360 - 180;
//     // const maxLon = ((x + 1) / Math.pow(2, level)) * 360 - 180;
//     const lon = minLon < 0 ? minLon + 360 : minLon;
//     const tileX: any = Math.floor((lon / 360) * Math.pow(2, level));
//     // 生成调整后的URL
//     const url = this._url.replace('{x}', tileX).replace('{y}', y).replace('{z}', level);
//     return Cesium.Resource.fetchImage({ url: url, request: request });
//   }
// }

/** 初始化场景 */
const initScene = (viewer: Cesium.Viewer) => {
  const scene: Cesium.Scene = viewer.scene;
  scene.backgroundColor = Cesium.Color.BLACK.withAlpha(0.5); // 设置背景透明
  // scene.globe.depthTestAgainstTerrain = false; //解决地形遮挡entity问题
  scene.globe.enableLighting = false; // 光照
  scene.postProcessStages.fxaa.enabled = false; // 关闭抗锯齿
  scene.debugShowFramesPerSecond = true;
  scene.screenSpaceCameraController.inertiaTranslate = 0;
  //
  const controller: Cesium.ScreenSpaceCameraController = scene.screenSpaceCameraController;
  controller.enableRotate = false; //旋转(平移)
  controller.enableTranslate = true; // 移动（2d，哥伦布）
  controller.enableZoom = true; //缩放
  controller.enableTilt = false; //倾斜相机
  controller.enableLook = true;
  controller.enableCollisionDetection = true; //碰撞检测
  controller.minimumZoomDistance = 100; //相机的高度的最小值
  controller.maximumZoomDistance = 18000000; //相机高度的最大值
  /**2D 模式下 禁止右键移动的时候，缩放地图 */
  scene.screenSpaceCameraController.zoomEventTypes = [Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.WHEEL];
  // 阻止地图根据ctrl + 左右键调整视角。
};

/** 初始化camera 相机 */
const initCamera = (viewer: Cesium.Viewer) => {
  viewer.scene.screenSpaceCameraController.enableRotate = false;
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(119.1679, 25.82, 3000000),
    orientation: {
      // 水平偏角，默认正北 0
      heading: 0,
      // 俯视角，默认-90，垂直向下
      pitch: Cesium.Math.toRadians(-90),
      // 旋转角
      roll: Cesium.Math.toRadians(0),
    },
  });
  // viewer.camera.flyTo({
  //   //经度、纬度、高度
  //   destination: Cesium.Cartesian3.fromDegrees(transfromLongitude(119.1679), 25.82, 3000000),
  //   orientation: {
  //     heading: 0,
  //     pitch: Cesium.Math.toRadians(-90),
  //     roll: Cesium.Math.toRadians(360),
  //   },
  //   duration: 1.0, //过渡时间
  // });
  // setTimeout(() => {}, 2000);
};
/** 销毁viewer */
export const viewerDestroy = (viewer: Cesium.Viewer) => {
  if (!viewer || viewer.isDestroyed()) return;
  // 1. 移除所有场景事件监听器
  // 清除当前选中的对象
  viewer.useDefaultRenderLoop = false;

  // 2. 移除所有屏幕空间事件处理器
  // if (viewer.scene.screenSpaceCameraController) {
  //   viewer.scene.screenSpaceCameraController.destroy();
  // }

  // 3. 移除所有图元选择相关的监听器
  viewer.selectedEntity = undefined;
  viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider();
  // 1. 移除所有实体(Entity)
  viewer.entities.removeAll();
  // 2. 移除所有数据源(DataSource)
  viewer.dataSources.removeAll();
  // // 3. 清理所有BillboardCollection
  cleanUpBillboardCollections(viewer.scene);
  // // 5. 清理影像图层
  while (viewer.imageryLayers.length > 0) {
    viewer.imageryLayers.remove(viewer.imageryLayers.get(0), true);
  }
  // // 8. 强制场景刷新(可选)
  // viewer.scene.requestRender();
  (viewer.scene as any)._frameState.commandList = [];
  (viewer.scene as any)._frameState.camera = undefined;
  (viewer.camera as any)._scene = undefined;
  (viewer.scene as any)._frameState.afterRender = [];
  // 四叉树瓦片缓存
  (viewer.scene.globe as any)._surface.tileProvider._cache = {};
  (viewer.scene.globe as any)._surface._tilesToRender = [];

  let gl: any = (viewer.scene as any).context._originalGLContext;
  (viewer.scene as any).context._originalGLContext = undefined;
  gl.canvas.width = 1;
  gl.canvas.height = 1;
  if (!viewer.isDestroyed()) {
    viewer.destroy();
  }
  while (viewer.container?.firstChild) {
    viewer.container.removeChild(viewer.container.firstChild);
  }

  // 使用完毕后手动销毁
  gl?.getExtension('WEBGL_lose_context')?.loseContext();
  gl = null;
};
function cleanUpBillboardCollections(scene: Cesium.Scene) {
  const primitives = scene.primitives;
  const length = primitives.length;
  // 从后向前遍历，因为移除元素会影响数组
  for (let i = length - 1; i >= 0; i--) {
    const primitive = primitives.get(i);
    // 检查是否是BillboardCollection或包含BillboardCollection
    if (primitive instanceof Cesium.BillboardCollection) {
      const length = primitive.length;
      for (let i = length - 1; i >= 0; i--) {
        let item: any = primitive.get(i);
        primitive.remove(item);
        item._pickPrimitive = undefined;
        item._collection = undefined;
        item._imageTexture._billboardCollection = undefined;
        item._imageTexture = undefined;
        item = undefined;
      }
      primitive.removeAll();
      primitives.remove(primitive);
      (primitive as any)._billboardTextureCache.clear();
    } else if (primitive instanceof Cesium.PrimitiveCollection) {
      // 如果是PrimitiveCollection，递归检查
      cleanUpNestedBillboards(primitive);
      // primitives.remove(primitive);
    } else if (primitive instanceof Cesium.PolylineCollection) {
      // clearPolylineCollection(primitive);
      primitive.removeAll();
      primitives.remove(primitive);
    }
  }
}

/**
 * 递归清理嵌套的BillboardCollection
 * @param {Cesium.PrimitiveCollection} collection
 */
function cleanUpNestedBillboards(collection: Cesium.PrimitiveCollection) {
  const length = collection.length;
  for (let i = length - 1; i >= 0; i--) {
    const item = collection.get(i);
    if (item instanceof Cesium.PrimitiveCollection) {
      cleanUpNestedBillboards(item);
    } else {
      if (item instanceof Cesium.Billboard) {
        (item as any)._pickPrimitive = undefined;
      }
      collection.remove(item);
    }
  }
}
